/*
 * Copyright (c) 2025 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "cloud_disk_js_manager.h"

#include "ipc_skeleton.h"
#include "tokenid_kit.h"
#include "file_access_framework_errno.h"
#include "file_access_service_client.h"

namespace OHOS {
namespace FileManagement {
using namespace FileAccessFwk;
#ifdef SUPPORT_CLOUD_DISK_MANAGER
constexpr int MAX_RETRY_TIMES = 3;
#endif

#ifdef SUPPORT_CLOUD_DISK_MANAGER
static bool IsSystemApp()
{
    uint64_t accessTokenIDEx = OHOS::IPCSkeleton::GetCallingFullTokenID();
    return OHOS::Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(accessTokenIDEx);
}
#endif

int CloudDiskJSManager::Register(const SyncFolder &syncFolder)
{
    HILOG_INFO("CloudDiskJSManager::Register in");
#ifdef SUPPORT_CLOUD_DISK_MANAGER
    auto proxy = FileAccessServiceClient::GetInstance();
    if (proxy == nullptr) {
        HILOG_ERROR("Register get SA failed");
        return E_LOAD_SA;
    }
    int ret = proxy->Register(syncFolder);
    int retryTimes = 1;
    while (ret == ERR_SERVICE_DIED && retryTimes <= MAX_RETRY_TIMES) {
        proxy = FileAccessServiceClient::GetInstance();
        if (proxy == nullptr) {
            HILOG_ERROR("Register get SA failed");
        } else {
            ret = proxy->Register(syncFolder);
        }
        ++retryTimes;
    }
    return ret;
#endif
    return ERR_NOT_SUPPORT;
}

int CloudDiskJSManager::Unregister(const std::string &path)
{
    HILOG_INFO("CloudDiskJSManager::Unregister in");
#ifdef SUPPORT_CLOUD_DISK_MANAGER
    auto proxy = FileAccessServiceClient::GetInstance();
    if (proxy == nullptr) {
        HILOG_ERROR("Unregister get SA failed");
        return E_LOAD_SA;
    }
    int ret = proxy->Unregister(path);
    int retryTimes = 1;
    while (ret == ERR_SERVICE_DIED && retryTimes <= MAX_RETRY_TIMES) {
        proxy = FileAccessServiceClient::GetInstance();
        if (proxy == nullptr) {
            HILOG_ERROR("Register get SA failed");
        } else {
            ret = proxy->Unregister(path);
        }
        ++retryTimes;
    }
    return ret;
#endif
    return ERR_NOT_SUPPORT;
}

int CloudDiskJSManager::Active(const std::string &path)
{
    HILOG_INFO("CloudDiskJSManager::Active in");
#ifdef SUPPORT_CLOUD_DISK_MANAGER
    auto proxy = FileAccessServiceClient::GetInstance();
    if (proxy == nullptr) {
        HILOG_ERROR("Active get SA failed");
        return E_LOAD_SA;
    }
    int ret = proxy->Active(path);
    int retryTimes = 1;
    while (ret == ERR_SERVICE_DIED && retryTimes <= MAX_RETRY_TIMES) {
        proxy = FileAccessServiceClient::GetInstance();
        if (proxy == nullptr) {
            HILOG_ERROR("Active get SA failed");
        } else {
            ret = proxy->Active(path);
        }
        ++retryTimes;
    }
    return ret;
#endif
    return ERR_NOT_SUPPORT;
}

int CloudDiskJSManager::Deactive(const std::string &path)
{
    HILOG_INFO("CloudDiskJSManager::Deactive in");
#ifdef SUPPORT_CLOUD_DISK_MANAGER
    auto proxy = FileAccessServiceClient::GetInstance();
    if (proxy == nullptr) {
        HILOG_ERROR("Deactive get SA failed");
        return E_LOAD_SA;
    }
    int ret = proxy->Deactive(path);
    int retryTimes = 1;
    while (ret == ERR_SERVICE_DIED && retryTimes <= MAX_RETRY_TIMES) {
        proxy = FileAccessServiceClient::GetInstance();
        if (proxy == nullptr) {
            HILOG_ERROR("Deactive get SA failed");
        } else {
            ret = proxy->Deactive(path);
        }
        ++retryTimes;
    }
    return ret;
#endif
    return ERR_NOT_SUPPORT;
}

int CloudDiskJSManager::GetSyncFolders(std::vector<SyncFolder> &syncFolders)
{
    HILOG_INFO("CloudDiskJSManager::GetSyncFolders in");
#ifdef SUPPORT_CLOUD_DISK_MANAGER
    auto proxy = FileAccessServiceClient::GetInstance();
    if (proxy == nullptr) {
        HILOG_ERROR("GetSyncFolders get SA failed");
        return E_LOAD_SA;
    }
    int ret = proxy->GetSyncFolders(syncFolders);
    int retryTimes = 1;
    while (ret == ERR_SERVICE_DIED && retryTimes <= MAX_RETRY_TIMES) {
        proxy = FileAccessServiceClient::GetInstance();
        if (proxy == nullptr) {
            HILOG_ERROR("GetSyncFolders get SA failed");
        } else {
            ret = proxy->GetSyncFolders(syncFolders);
        }
        ++retryTimes;
    }
    return ret;
#endif
    return ERR_NOT_SUPPORT;
}

int CloudDiskJSManager::GetAllSyncFolders(std::vector<SyncFolderExt> &syncFolderExts)
{
    HILOG_INFO("CloudDiskJSManager::GetAllSyncFolders in");
#ifdef SUPPORT_CLOUD_DISK_MANAGER
    if (!IsSystemApp()) {
        HILOG_ERROR("GetAllSyncFolders check IsSystemAppByFullTokenID failed");
        return E_PERMISSION_SYS;
    }
    auto proxy = FileAccessServiceClient::GetInstance();
    if (proxy == nullptr) {
        HILOG_ERROR("GetAllSyncFolders get SA failed");
        return E_LOAD_SA;
    }
    int ret = proxy->GetAllSyncFolders(syncFolderExts);
    int retryTimes = 1;
    while (ret == ERR_SERVICE_DIED && retryTimes <= MAX_RETRY_TIMES) {
        proxy = FileAccessServiceClient::GetInstance();
        if (proxy == nullptr) {
            HILOG_ERROR("GetAllSyncFolders get SA failed");
        } else {
            ret = proxy->GetAllSyncFolders(syncFolderExts);
        }
        ++retryTimes;
    }
    return ret;
#endif
    return ERR_NOT_SUPPORT;
}

int CloudDiskJSManager::UpdateDisplayName(const std::string &path, const std::string &displayName)
{
    HILOG_INFO("CloudDiskJSManager::UpdateDisplayName in");
#ifdef SUPPORT_CLOUD_DISK_MANAGER
    auto proxy = FileAccessServiceClient::GetInstance();
    if (proxy == nullptr) {
        HILOG_ERROR("UpdateDisplayName get SA failed");
        return E_LOAD_SA;
    }
    int ret = proxy->UpdateDisplayName(path, displayName);
    int retryTimes = 1;
    while (ret == ERR_SERVICE_DIED && retryTimes <= MAX_RETRY_TIMES) {
        proxy = FileAccessServiceClient::GetInstance();
        if (proxy == nullptr) {
            HILOG_ERROR("UpdateDisplayName get SA failed");
        } else {
            ret = proxy->UpdateDisplayName(path, displayName);
        }
        ++retryTimes;
    }
    return ret;
#endif
    return ERR_NOT_SUPPORT;
}
} // namespace FileAccessFwk
} // namespace OHOS
